home *** CD-ROM | disk | FTP | other *** search
- /*
- * The original copyright owners of the accompanying source code files have
- * agreed to place such code into the public domain. Accordingly, anyone
- * who receives or obtains a copy of such source code is freely entitled to
- * reproduce, use and otherwise exploit such code (including the right to
- * make derivative works), at his/her own risk and expense, without any
- * obligation or liability to the original copyright owners.
- *
- * We would appreciate (but do not require) that the following message be
- * included in any derivative works:
- *
- * "Portions of this program were developed by Peter Broadwell, Rob Myers
- * and Robin Schaufler while working in Silicon Valley."
- *
- * The accompanying source code files and related documentation materials
- * are distributed on an "AS IS" basis, without any warranties or
- * guarantees of any kind. All implied warranties, including the implied
- * warranties of merchantability and of fitness for any particular purpose,
- * are expressly disclaimed.
- */
- #include <stdio.h>
- #include <math.h>
- #include <gl.h>
- #include <device.h>
-
- #include "geom.h"
- #include "selectors.h"
- #include "class.h"
- #include "classIds.h"
- #include "mbox.h"
- #include "behavior.h"
-
- extern int maldbug;
- extern int dumper;
- #ifdef MALDEBUG
- #define Free(a) if(maldbug) printf("gffree(0x%x)\n",a); gffree(a)
- #else
- #define Free(a) gffree(a)
- #endif /* MALDEBUG */
-
-
- /*
- * add subscriber to a mailbox
- */
- subscribe(self, subscriber)
- register mailbox *self;
- mailbox *subscriber;
- {
- register behavior *bself = (behavior *)self;
- register subscr *myNewEntry, *hisNewEntry;
-
- /*if(maldbug) printf("subscribe(0x%x, 0x%x)\n",self,subscriber);*/
-
- myNewEntry = (subscr *)gfmalloc(sizeof(subscr));
- if(!myNewEntry) {
- fprintf(stderr,"subscribe: my gfmalloc bombed out\n");
- exit(1);
- }
- /*
- * if subscribing to a behavior, get instance vars-sized
- * subscr entry
- */
- if (isSuper(self, BEHAVIOR) && bself->vartemplate) {
- hisNewEntry = (subscr *)gfmalloc(bself->varsize);
- if(!hisNewEntry) {
- fprintf(stderr,"subscribe: his vartemplate gfmalloc bombed out\n");
- exit(1);
- }
- /* initialize instance variables from template */
- bcopy(bself->vartemplate, hisNewEntry, bself->varsize);
- }
- else {
- hisNewEntry = (subscr *)gfmalloc(sizeof(subscr));
- if(!hisNewEntry) {
- fprintf(stderr,"subscribe: his gfmalloc bombed out\n");
- exit(1);
- }
- }
-
- myNewEntry->next = self->subscribers;
- myNewEntry->member = (inst *)subscriber;
- self->subscribers = myNewEntry;
-
- hisNewEntry->next = subscriber->subscribedTo;
- hisNewEntry->member = (inst *)self;
- subscriber->subscribedTo = hisNewEntry;
- }
-
- /*
- * remove subscriber from a mailbox
- */
- unsubscribe(self, unsubscriber)
- register mailbox *self;
- mailbox *unsubscriber;
- {
- subscr *unLinkMember();
-
- /*if(maldbug) printf("unsubscribe(0x%x, 0x%x)\n",self,unsubscriber);*/
-
- self->subscribers = unLinkMember(self->subscribers, unsubscriber);
- dumpSubscribers("FPost",self->subscribers,unsubscriber);
- unsubscriber->subscribedTo =
- unLinkMember(unsubscriber->subscribedTo, self);
- dumpSubscribers("Post",unsubscriber->subscribedTo,self);
- }
-
- /*
- * unlink a subscription entry from a subscription list
- */
- subscr *
- unLinkMember(list, member)
- subscr *list;
- mailbox *member;
- {
- register subscr *entry, *nentry;
-
- if(! list || ! member)
- return list;
- dumpSubscribers("pre",list,member);
- if(list->member == (inst *)member) { /* first thing in list */
- nentry = list->next;
- gffree(list);
- dumpSubscribers("fpost",nentry,member);
- return nentry;
- }
- for (entry = list; entry; entry = entry->next) {
- if (nentry = entry->next) {
- if (nentry->member == (inst *)member) {
- entry->next = nentry->next;
- gffree(nentry);
- }
- }
- }
- dumpSubscribers("post",list,member);
- return list;
- }
-
- #ifdef NOTDEF
- /*
- * gffree entry. other implementations may gffree pointers from entry.
- */
- freevars(self, argtype, entry)
- mailbox *self;
- int argtype;
- subscr *entry;
- {
- Free(entry);
- }
- #endif /* NOTDEF */
-
- /*
- * find the instance variable block for class(catagory) within a subscriber
- */
- subscr *
- findvars(self, catagory)
- register mailbox *self;
- int catagory;
- {
- register subscr *entry;
- inst *member;
-
- for (entry = self->subscribedTo; entry; entry = entry->next) {
- if ((member = entry->member) && isSuper(member, catagory))
- return entry;
- }
- return NULL;
- }
-
- /*
- * halfway add subscriber to a mailbox, for future use.
- * used by eggs to remember to subscribe their offspring later.
- */
- halfsubscr(self, subscriber)
- register mailbox *self;
- mailbox *subscriber;
- {
- register behavior *bself = (behavior *)self;
- register subscr *hisNewEntry;
-
- /*
- * if subscribing to a behavior, get instance vars-sized
- * subscr entry
- */
- if (isSuper(self, BEHAVIOR) && bself->vartemplate) {
- hisNewEntry = (subscr *)gfmalloc(bself->varsize);
- /* initialize instance variables from template */
- bcopy(bself->vartemplate, hisNewEntry, bself->varsize);
- }
- else {
- hisNewEntry = (subscr *)gfmalloc(sizeof(subscr));
- }
-
- hisNewEntry->next = subscriber->subscribedTo;
- hisNewEntry->member = (inst *)self;
- subscriber->subscribedTo = hisNewEntry;
-
- }
-
- /*
- * dump a subscription list
- */
- dumpSubscribers(string, slist, wanted)
- char *string;
- register subscr *slist;
- inst *wanted;
- {
- register subscr *s;
-
- if(!dumper) return;
-
- printf("dumpSubscribers: %s want 0x%x\n",string,wanted);
- for (s = slist; s; s = s->next) {
- printf("\t 0x%x subscr->member = 0x%x",s,s->member);
- if (s->member)
- printf(", class %d", s->member->myClass->classId);
- if (s->member == wanted)
- printf("\t<<<<<<");
- printf("\n");
- }
- }
-